<?php
/**
 * Create by PhpStorm
 * User: lcz
 * DATE: 2019/8/28
 * Time: 11:09
 * 登录
 */

namespace app\api\controller;

use app\admin\model\User;
use app\common\controller\Api;
use app\common\library\Weixin;
use app\extra\WXBizDataCrypt;
use think\Db;
use think\Exception;

class Login extends Api {
	protected $noNeedRight = ['*'];
	protected $noNeedLogin = ['smallapp', 'getauthurl'];
	
	
	/**
	 * 小程序的登录
	 */
	public function smallapp() {
		$code = $this->request->post('code');
		!$code && $this->error('参数错误');
		
		$appId = $this->getAppid();
		$weixin = new Weixin($appId);
		
		//获取openid和session_key
		$res = $weixin->getOpenId($code);
		if (!$res) {
			$this->error('授权出错，请稍候重试！', $res);
		}
		
		$openid = $res['openid'];
		//判断是要培训还是大招宝
		$key = $this->platform == 'school' ? 'school_openId' : 'openId';
		//查看用户是否存在
		$row = Db::name('user')
			->where([$key => $openid])
			->lock(true)
			->field('uid')
			->find();
		
		if (!$row) {
			
			$data = [
				$key => $openid,
				'sessionKey' => $res['session_key'],
			];
			
			$username = 'wx_' . mt_rand(111111, 999999);
			$password = mt_rand(111111, 999999);
			
			$ret = $this->auth->register($username, $password, '', '',
				$data);
			if (!$ret) {
				$this->error($this->auth->getError());
			}
			$userId = $this->auth->uid;
		} else {
			$userId = $row['uid'];
		}
		
		//已经有帐号，直接登录
		$info = $this->getReturnUserInfo($userId);
		if ($info) {
			$this->success('登录成功', $info);
		} else {
			$this->error($this->auth->getError());
		}
		
		
	}
	
	/**
	 * 获取unionId的操作
	 */
	public function union() {
		$code = $this->request->post('code');
		!$code && $this->error('参数错误');
		$postData = input('post.');
		
		$appId = $this->getAppid();
		$weixin = new Weixin($appId);
		
		//获取openid和session_key
		$res = $weixin->getOpenId($code);
		if (!isset($res['openid'])) {
			$this->error('授权出错，请稍候重试！', $res);
		}
		
		
		$sessionKey = $res['session_key'];
		$openId = $res['openid'];
		$pc = new WXBizDataCrypt($appId, $sessionKey);
		$data = [];
		$errCode = $pc->decryptData($postData['encryptedData'], $postData['iv'], $data);
		if($errCode != 0) {
			$this->error('解密出错，请重试');
		}
		
		$data = json_decode($data, true);
		$unionId = $data['unionId'];
		//查看用户是否存在
		$row = Db::name('user')
			->where(['unionId' => $unionId])
			->field('uid, unionId, openId, school_openId')
			->find();
		
		$userId = $this->auth->uid;
		
		
		Db::startTrans();
		try {
			if ($row) {
				//有登录过
				$key = $this->platform == 'school' ? 'school_openId' : 'openId';
				
				if($row[$key] != $openId) {
					//如果UnionId的用户
					//禁用新注册的用户
					$delRes = Db::name('user')
						->where([$key => $openId])
						->update([
							$key => $userId,
							'status' => User::STATUS_D
						]);
					if($delRes === false) {
						
						throw new Exception('更改现在的帐号信息出错');
					}
				}
				
				//之前已经有了用户信息，把之前的信息更新，现在的禁用掉
				$updateData = [
					'unionId' => $unionId,
					'avatar' => $postData['avatarUrl'],
					'nick' => $postData['nickName'],
					$key => $openId
				];
				$res = Db::name('user')
					->where(['uid' => $row['uid']])
					->update($updateData);
				
				if($res === false) {
					throw new Exception('更新原来的帐号出错');
				}
				$userId = $row['uid'];
			} else {
				$data = [
					'sessionKey' => $sessionKey,
					'unionId' => $unionId,
					'avatar' => $postData['avatarUrl'],
					'nick' => $postData['nickName']
				];
				
				$res = Db::name('user')
					->where(['uid' => $userId])
					->update($data);
				if($res === false) {
					throw new Exception('更新帐号信息出错');
				}
			}
			
			$info = $this->getReturnUserInfo($userId);
			if (!$info) {
				throw new Exception('登录失败');
			}
			
			Db::commit();
			$this->success('保存成功', $info);
		} catch (Exception $e) {
			Db::rollback();
			$this->error('保存信息出错', [
				'error' => $e->getMessage(),
			]);
		}
		
	}
	
	/**
	 * 获取登录后要返回的用户信息
	 * @param $userId
	 * @return array|bool
	 */
	private function getReturnUserInfo($userId){
		//登录
		$ret = $this->auth->direct($userId);
		if ($ret) {
			$userInfo = $this->auth->getUserinfo();
			
			$time = time();
			$info = [
				'loginUid' => $userInfo['uid'],
				'loginTime' => $time,
				'loginKey' => $this->auth->getKey($time, $userInfo['uid']),
				'mobile' => $userInfo['mobile'],
				'avatar' => $userInfo['avatar'],
				'token' => $this->auth->getToken(),
				'unionId' => $userInfo['unionId']
			];
			
			return $info;
		} else {
			return false;
		}
	}
	
	/**
	 * 微信公众号获取授权地址
	 */
	public function getAuthUrl() {
		//用户授权后的返回地址
		$config = config('weixin.public');
		$returnUrl = urldecode($this->request->post('callback_url'));
		$url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' . $config['app_id'] . '&redirect_uri=' .$returnUrl . '&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect';
		$this->success('操作成功', $url);
	}
	
	/**
	 * 授权回调地址
	 * @return mixed
	 */
	public function wxLogin() {
		//返回的code
		$code = $this->request->post('code');
		!$code && $this->error('参数错误');
		
		//公众号配置信息
		$config = config('weixin.public');
		
		//获取openID
		$token_url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $config['app_id'] . '&secret=' . $config['app_secret'] . '&code=' . $code . '&grant_type=authorization_code';
		
		$res = curl_get_info($token_url);
		if (!isset($res['openid'])) {
			$this->error('获取openId出错', $res);
		}
		$openid = $res['openid'];
		
		$weixin = new Weixin($config['app_id']);
		
		$info = $weixin->getNoFcouseUserInfo($res['access_token'], $openid);
		if(!$info) {
			$this->error('获取用户信息出错', $info);
		}
		
		//查看用户是否存在
//		$row = Db::name('user')
//			->where(['public_openid' => $openid])
//			->lock(true)
//			->field('id')
//			->find();
		$row = User::get($this->auth->id);
		
		$data = [
			'public_openid' => $openid
		];
		
		if(isset($info['headimgurl'])) {
			$data['avatar'] = $info['headimgurl'];
		}
		
		if(isset($info['nickname'])) {
			$data['nickname'] = $info['nickname'];
		}
		
		if ($row) {
			Db::name('user')
				->where(['id' => $row['id']])
				->update($data);
			
			//用户存在，登录
			$ret = $this->auth->direct($row['id']);
			if (!$ret) {
				$this->error($this->auth->getError());
			}
		} else {
			$username = 'wx_' . mt_rand(111111, 999999);
			$password = mt_rand(111111, 999999);
			$ret = $this->auth->register($username, $password, '', '', $data);
			if (!$ret) {
				$this->error($this->auth->getError());
			}
		}
		
		$userInfo = $this->auth->getUserinfo();
		$this->success($row?'绑定成功':'注册成功', $userInfo);
		
	}
}